home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Dev / C / Tinygl.lha / TinyGL / src / zbuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-16  |  11.3 KB  |  529 lines

  1. /*
  2.  
  3.  * Z buffer: 16 bits Z / 16 bits color
  4.  *
  5.  */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <assert.h>
  9. #include <string.h>
  10. #include "zbuffer.h"
  11.  
  12. ZBuffer *ZB_open(int xsize, int ysize, int mode,
  13.                  int nb_colors,
  14.                  unsigned char *color_indexes,
  15.                  int *color_table,
  16.                  void *frame_buffer)
  17. {
  18.     ZBuffer *zb;
  19.     int size;
  20.  
  21.     zb = gl_malloc(sizeof(ZBuffer));
  22.     if (zb == NULL)
  23.         return NULL;
  24.  
  25.     zb->xsize = xsize;
  26.     zb->ysize = ysize;
  27.     zb->mode = mode;
  28.     zb->linesize = (xsize * PSZB + 3) & ~3;
  29.  
  30.     switch (mode) {
  31. #ifdef TGL_FEATURE_8_BITS
  32.     case ZB_MODE_INDEX:
  33.         ZB_initDither(zb, nb_colors, color_indexes, color_table);
  34.         break;
  35. #endif
  36. #ifdef TGL_FEATURE_32_BITS
  37.     case ZB_MODE_RGBA:
  38. #endif
  39. #ifdef TGL_FEATURE_24_BITS
  40.     case ZB_MODE_RGB24:
  41. #endif
  42.     case ZB_MODE_5R6G5B:
  43.         zb->nb_colors = 0;
  44.         break;
  45.     default:
  46.         goto error;
  47.     }
  48.  
  49.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  50.  
  51.     zb->zbuf = gl_malloc(size);
  52.     if (zb->zbuf == NULL)
  53.         goto error;
  54.  
  55.     if (frame_buffer == NULL) {
  56.         zb->pbuf = gl_malloc(zb->ysize * zb->linesize);
  57.         if (zb->pbuf == NULL) {
  58.             gl_free(zb->zbuf);
  59.             goto error;
  60.         }
  61.         zb->frame_buffer_allocated = 1;
  62.     } else {
  63.         zb->frame_buffer_allocated = 0;
  64.         zb->pbuf = frame_buffer;
  65.     }
  66.  
  67.     zb->current_texture = NULL;
  68.  
  69.     return zb;
  70.   error:
  71.     gl_free(zb);
  72.     return NULL;
  73. }
  74.  
  75. void ZB_close(ZBuffer * zb)
  76. {
  77.  
  78. #ifdef TGL_FEATURE_8_BITS
  79.     if (zb->mode == ZB_MODE_INDEX)
  80.         ZB_closeDither(zb);
  81. #endif
  82.  
  83.     if (zb->frame_buffer_allocated)
  84.         gl_free(zb->pbuf);
  85.                 
  86.         if (zb->zbuf)
  87.             gl_free(zb->zbuf);
  88.         
  89.     gl_free(zb);
  90. }
  91.  
  92. void ZB_resize(ZBuffer * zb, void *frame_buffer, int xsize, int ysize)
  93. {
  94.     int size;
  95.                 
  96.     /* xsize must be a multiple of 4 */
  97.     xsize = xsize & ~3;
  98.  
  99.     zb->xsize = xsize;
  100.     zb->ysize = ysize;
  101.     zb->linesize = (xsize * PSZB + 3) & ~3;
  102.  
  103.     size = zb->xsize * zb->ysize * sizeof(unsigned short);
  104.  
  105.     gl_free(zb->zbuf);
  106.     zb->zbuf = gl_malloc(size);
  107.  
  108.     if (zb->frame_buffer_allocated)
  109.         gl_free(zb->pbuf);
  110.  
  111.     if (frame_buffer == NULL) {
  112.         zb->pbuf = gl_malloc(zb->ysize * zb->linesize);
  113.         zb->frame_buffer_allocated = 1;
  114.     } else {
  115.         zb->pbuf = frame_buffer;
  116.         zb->frame_buffer_allocated = 0;
  117.     }
  118. }
  119.  
  120. static void ZB_copyBuffer(ZBuffer * zb,
  121.                           void *buf,
  122.                           int linesize)
  123. {
  124.     unsigned char *p1;
  125.     PIXEL *q;
  126.     int y, n;
  127.  
  128.     q = zb->pbuf;
  129.     p1 = buf;
  130.     n = zb->xsize * PSZB;
  131.     for (y = 0; y < zb->ysize; y++) {
  132.         memcpy(p1, q, n);
  133.         p1 += linesize;
  134.         q = (PIXEL *) ((char *) q + zb->linesize);
  135.     }
  136. }
  137.  
  138. #if TGL_FEATURE_RENDER_BITS == 16
  139.  
  140. /* 32 bpp copy */
  141.  
  142. #ifdef TGL_FEATURE_32_BITS
  143.  
  144. #define RGB16_TO_RGB32(p0,p1,v)\
  145. {\
  146.     unsigned int g,b,gb;\
  147.     g = (v & 0x07E007E0) << 5;\
  148.     b = (v & 0x001F001F) << 3;\
  149.     gb = g | b;\
  150.     p0 = (gb & 0x0000FFFF) | ((v & 0x0000F800) << 8);\
  151.     p1 = (gb >> 16) | ((v & 0xF8000000) >> 8);\
  152. }
  153.  
  154. static void ZB_copyFrameBufferRGB32(ZBuffer * zb,
  155.                                     void *buf,
  156.                                     int linesize)
  157. {
  158.     unsigned short *q;
  159.         unsigned int *p, v, w0, w1;
  160.     int y, n;
  161.  
  162.     q = zb->pbuf;
  163.     //p1 = (unsigned int *) buf;
  164.     p = (unsigned int *) buf;
  165.  
  166.     for (y = 0; y < zb->ysize; y++) {
  167.         //p = p1;
  168.         n = zb->xsize >> 2;
  169.         do {
  170.             v = *(unsigned int *) q;
  171. #if BYTE_ORDER == BIG_ENDIAN
  172.             RGB16_TO_RGB32(w1, w0, v);
  173. #else
  174.             RGB16_TO_RGB32(w0, w1, v);
  175. #endif
  176.             p[0] = w0;
  177.             p[1] = w1;
  178.  
  179.             v = *(unsigned int *) (q + 2);
  180. #if BYTE_ORDER == BIG_ENDIAN
  181.             RGB16_TO_RGB32(w1, w0, v);
  182. #else
  183.             RGB16_TO_RGB32(w0, w1, v);
  184. #endif
  185.             p[2] = w0;
  186.             p[3] = w1;
  187.  
  188.             q += 4;
  189.             p += 4;
  190.         } while (--n > 0);
  191.  
  192.         //(char *)p1 += linesize;
  193.     }
  194. }
  195.  
  196. #endif
  197.  
  198. /* 24 bit packed pixel handling */
  199.  
  200. #ifdef TGL_FEATURE_24_BITS
  201.  
  202. /* order: RGBR GBRG BRGB */
  203.  
  204. /* XXX: packed pixel 24 bit support not tested */
  205. /* XXX: big endian case not optimised */
  206.  
  207. #if BYTE_ORDER == BIG_ENDIAN
  208.  
  209. #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
  210. {\
  211.     unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
  212.     v1 = (v1 << 16) | (v1 >> 16);\
  213.     v2 = (v2 << 16) | (v2 >> 16);\
  214.     r1 = (v1 & 0xF800F800);\
  215.     g1 = (v1 & 0x07E007E0) << 5;\
  216.     b1 = (v1 & 0x001F001F) << 3;\
  217.     gb1 = g1 | b1;\
  218.     p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
  219.     g2 = (v2 & 0x07E007E0) << 5;\
  220.     b2 = (v2 & 0x001F001F) << 3;\
  221.     gb2 = g2 | b2;\
  222.     p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
  223.     p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
  224. }
  225.  
  226. #else
  227.  
  228. #define RGB16_TO_RGB24(p0,p1,p2,v1,v2)\
  229. {\
  230.     unsigned int r1,g1,b1,gb1,g2,b2,gb2;\
  231.     r1 = (v1 & 0xF800F800);\
  232.     g1 = (v1 & 0x07E007E0) << 5;\
  233.     b1 = (v1 & 0x001F001F) << 3;\
  234.     gb1 = g1 | b1;\
  235.     p0 = ((gb1 & 0x0000FFFF) << 8) | (r1 << 16) | (r1 >> 24);\
  236.     g2 = (v2 & 0x07E007E0) << 5;\
  237.     b2 = (v2 & 0x001F001F) << 3;\
  238.     gb2 = g2 | b2;\
  239.     p1 = (gb1 & 0xFFFF0000) | (v2 & 0xF800) | ((gb2 >> 8) & 0xff);\
  240.     p2 = (gb2 << 24) | ((v2 & 0xF8000000) >> 8) | (gb2 >> 16);\
  241. }
  242.  
  243. #endif
  244.  
  245. static void ZB_copyFrameBufferRGB24(ZBuffer * zb,
  246.                                     void *buf,
  247.                                     int linesize)
  248. {
  249.     unsigned short *q;
  250.         unsigned int *p,w0, w1, w2, v0, v1;
  251.     int y, n;
  252.  
  253.     q = zb->pbuf;
  254.     //p1 = (unsigned int *) buf;
  255.     p = (unsigned int *) buf;
  256.  
  257.     linesize = linesize * 3;
  258.  
  259.     for (y = 0; y < zb->ysize; y++) {
  260.         //p = p1;
  261.         n = zb->xsize >> 2;
  262.         do {
  263.             v0 = *(unsigned int *) q;
  264.             v1 = *(unsigned int *) (q + 2);
  265.             RGB16_TO_RGB24(w0, w1, w2, v0, v1);
  266.             p[0] = w0;
  267.             p[1] = w1;
  268.             p[2] = w2;
  269.  
  270.             q += 4;
  271.             p += 3;
  272.         } while (--n > 0);
  273.  
  274.         /* ((char *) p1) += linesize;*/
  275.         //p1=(unsigned int *)&((char *)p1)[linesize];
  276.     }
  277. }
  278.  
  279. #endif
  280.  
  281. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  282.                         int linesize)
  283. {
  284.     switch (zb->mode) {
  285. #ifdef TGL_FEATURE_8_BITS
  286.     case ZB_MODE_INDEX:
  287.         ZB_ditherFrameBuffer(zb, buf, linesize >> 1);
  288.         break;
  289. #endif
  290. #ifdef TGL_FEATURE_16_BITS
  291.     case ZB_MODE_5R6G5B:
  292.         ZB_copyBuffer(zb, buf, linesize);
  293.         break;
  294. #endif
  295. #ifdef TGL_FEATURE_32_BITS
  296.     case ZB_MODE_RGBA:
  297.         ZB_copyFrameBufferRGB32(zb, buf, linesize >> 1);
  298.         break;
  299. #endif
  300. #ifdef TGL_FEATURE_24_BITS
  301.     case ZB_MODE_RGB24:
  302.         ZB_copyFrameBufferRGB24(zb, buf, linesize >> 1);
  303.         break;
  304. #endif
  305.     default:
  306.         assert(0);
  307.     }
  308. }
  309.  
  310. #endif /* TGL_FEATURE_RENDER_BITS == 16 */
  311.  
  312. #if TGL_FEATURE_RENDER_BITS == 24
  313.  
  314. #define RGB24_TO_RGB16(r, g, b) \
  315.   ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
  316.  
  317. /* XXX: not optimized */
  318. static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
  319.                                      void *buf, int linesize)
  320. {
  321.     PIXEL *q;
  322.     unsigned short *p, *p1;
  323.     int y, n;
  324.  
  325.     q = zb->pbuf;
  326.     p1 = (unsigned short *) buf;
  327.  
  328.     for (y = 0; y < zb->ysize; y++) {
  329.         p = p1;
  330.         n = zb->xsize >> 2;
  331.         do {
  332.             p[0] = RGB24_TO_RGB16(q[0], q[1], q[2]);
  333.             p[1] = RGB24_TO_RGB16(q[3], q[4], q[5]);
  334.             p[2] = RGB24_TO_RGB16(q[6], q[7], q[8]);
  335.             p[3] = RGB24_TO_RGB16(q[9], q[10], q[11]);
  336.             q = (PIXEL *)((char *)q + 4 * PSZB);
  337.             p += 4;
  338.         } while (--n > 0);
  339.         p1 = (unsigned short *)((char *)p1 + linesize);
  340.     }
  341. }
  342.  
  343. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  344.                         int linesize)
  345. {
  346.     switch (zb->mode) {
  347. #ifdef TGL_FEATURE_16_BITS
  348.     case ZB_MODE_5R6G5B:
  349.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  350.         break;
  351. #endif
  352. #ifdef TGL_FEATURE_24_BITS
  353.     case ZB_MODE_RGB24:
  354.         ZB_copyBuffer(zb, buf, linesize);
  355.         break;
  356. #endif
  357.     default:
  358.         assert(0);
  359.     }
  360. }
  361.  
  362. #endif /* TGL_FEATURE_RENDER_BITS == 24 */
  363.  
  364. #if TGL_FEATURE_RENDER_BITS == 32
  365.  
  366. #define RGB32_TO_RGB16(v) \
  367.   (((v >> 8) & 0xf800) | (((v) >> 5) & 0x07e0) | (((v) & 0xff) >> 3))
  368.  
  369. /* XXX: not optimized */
  370. static void ZB_copyFrameBuffer5R6G5B(ZBuffer * zb,
  371.                                      void *buf, int linesize)
  372. {
  373.     PIXEL *q;
  374.     unsigned short *p, *p1;
  375.     int y, n;
  376.  
  377.     q = zb->pbuf;
  378.     p1 = (unsigned short *) buf;
  379.  
  380.     for (y = 0; y < zb->ysize; y++) {
  381.         p = p1;
  382.         n = zb->xsize >> 2;
  383.         do {
  384.             p[0] = RGB32_TO_RGB16(q[0]);
  385.             p[1] = RGB32_TO_RGB16(q[1]);
  386.             p[2] = RGB32_TO_RGB16(q[2]);
  387.             p[3] = RGB32_TO_RGB16(q[3]);
  388.             q += 4;
  389.             p += 4;
  390.         } while (--n > 0);
  391.         p1 = (unsigned short *)((char *)p1 + linesize);
  392.     }
  393. }
  394.  
  395. void ZB_copyFrameBuffer(ZBuffer * zb, void *buf,
  396.                         int linesize)
  397. {
  398.     switch (zb->mode) {
  399. #ifdef TGL_FEATURE_16_BITS
  400.     case ZB_MODE_5R6G5B:
  401.         ZB_copyFrameBuffer5R6G5B(zb, buf, linesize);
  402.         break;
  403. #endif
  404. #ifdef TGL_FEATURE_32_BITS
  405.     case ZB_MODE_RGBA:
  406.         ZB_copyBuffer(zb, buf, linesize);
  407.         break;
  408. #endif
  409.     default:
  410.         assert(0);
  411.     }
  412. }
  413.  
  414. #endif /* TGL_FEATURE_RENDER_BITS == 32 */
  415.  
  416.  
  417. /*
  418.  * adr must be aligned on an 'int'
  419.  */
  420. void memset_s(void *adr, int val, int count)
  421. {
  422.     int i, n, v;
  423.     unsigned int *p;
  424.     unsigned short *q;
  425.  
  426.     p = adr;
  427.     v = val | (val << 16);
  428.  
  429.     n = count >> 3;
  430.     for (i = 0; i < n; i++) {
  431.         p[0] = v;
  432.         p[1] = v;
  433.         p[2] = v;
  434.         p[3] = v;
  435.         p += 4;
  436.     }
  437.  
  438.     q = (unsigned short *) p;
  439.     n = count & 7;
  440.     for (i = 0; i < n; i++)
  441.         *q++ = val;
  442. }
  443.  
  444. void memset_l(void *adr, int val, int count)
  445. {
  446.     int i, n, v;
  447.     unsigned int *p;
  448.         
  449.     p = adr;
  450.     v = val;
  451.     n = count >> 2;
  452.     for (i = 0; i < n; i++) {
  453.         p[0] = v;
  454.         p[1] = v;
  455.         p[2] = v;
  456.         p[3] = v;
  457.         p += 4;
  458.     }
  459.  
  460.     n = count & 3;
  461.     for (i = 0; i < n; i++)
  462.         *p++ = val;
  463. }
  464.  
  465. /* count must be a multiple of 4 and >= 4 */
  466. void memset_RGB24(void *adr,int r, int v, int b,long count)
  467. {
  468.     long i, n;
  469.     register long v1,v2,v3,*pt=(long *)(adr);
  470.     unsigned char *p,R=(unsigned char)r,V=(unsigned char)v,B=(unsigned char)b;
  471.  
  472.     p=(unsigned char *)adr;
  473.     *p++=R;
  474.     *p++=V;
  475.     *p++=B;
  476.     *p++=R;
  477.     *p++=V;
  478.     *p++=B;
  479.     *p++=R;
  480.     *p++=V;
  481.     *p++=B;
  482.     *p++=R;
  483.     *p++=V;
  484.     *p++=B;
  485.     v1=*pt++;
  486.     v2=*pt++;
  487.     v3=*pt++;
  488.     n = count >> 2;
  489.     for(i=1;i<n;i++) {
  490.         *pt++=v1;
  491.         *pt++=v2;
  492.         *pt++=v3;
  493.     }
  494. }
  495.  
  496. void ZB_clear(ZBuffer * zb, int clear_z, int z,
  497.               int clear_color, int r, int g, int b)
  498. {
  499. #if TGL_FEATURE_RENDER_BITS != 24
  500.     int color;
  501. #endif
  502.     int y;
  503.     PIXEL *pp;
  504.  
  505.         // Clear the Z buffer
  506.     if (clear_z) {
  507.         memset_s(zb->zbuf, z, zb->xsize * zb->ysize);
  508.     }
  509.  
  510.         // Clear the frame buffer
  511.     if (clear_color) {
  512.         pp = zb->pbuf;
  513.         for (y = 0; y < zb->ysize; y++) {
  514. #if TGL_FEATURE_RENDER_BITS == 15 || TGL_FEATURE_RENDER_BITS == 16
  515.             color = RGB_TO_PIXEL(r, g, b);
  516.             memset_s(pp, color, zb->xsize);
  517. #elif TGL_FEATURE_RENDER_BITS == 32
  518.             color = RGB_TO_PIXEL(r, g, b);
  519.             memset_l(pp, color, zb->xsize);
  520. #elif TGL_FEATURE_RENDER_BITS == 24
  521.             memset_RGB24(pp,r>>8,g>>8,b>>8,zb->xsize);
  522. #else
  523. #error TODO
  524. #endif
  525.             pp = (PIXEL *) ((char *) pp + zb->linesize);
  526.         }
  527.     }
  528. }
  529.